<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"
    />
    <title>发布观察者模式</title>
</head>

<body>
    <p>我们已经实现了一个最简单的发布 — 订阅模式，但这里还存在一些问题。我们看到订 阅者接收到了发布者发布的每个消息，虽然小明只想买 88 平方米的房子，但是发布者把 110 平 方米的信息也推送给了小明，这对小明来说是不必要的困扰。所以我们有必要增加一个标示
        key ， 让订阅者只订阅自己感兴趣的消息。。</p>

    <div id="release">发布售楼信息</div>
    <script type="text/javascript">
            (function (window) {
                var salesOffices = {}; // 售楼处
                salesOffices.clientList = {}; // 缓存列表，存放订阅者的回调函数
                salesOffices.listen = function (key, fn) { // 新增订阅者
                    if (!this.clientList[key]) {
                        this.clientList[key] = [];
                    }
                    this.clientList[key].push(fn);
                }
                salesOffices.trigger = function () {
                    var key = Array.prototype.shift.call(arguments); // 取出消息类型
                    var fns = this.clientList[key]; // 取出该消息对应的回调函数集合

                    if (!fns || fns.length === 0) { // 如果没有订阅该消息，则返回
                        return false;
                    }
                    for (var i = 0, fn; fn = fns[i++];) {
                        fn.apply(this, arguments); // (2) // arguments 是发布消息时附送的参数
                    }
                }

                window.salesOffices = salesOffices;
            })(window)

        salesOffices.listen('squareMeter88', function (price, squareMeter) { // 小明订阅88平米房子的消息
            console.log('小明：价格= ' + price + '，面积= ' + squareMeter);
        });
        salesOffices.listen('squareMeter60', function (price, squareMeter) { // 小红订阅60平米房子消息
            console.log('小红：价格= ' + price + '，面积= ' + squareMeter);
        });


        // 发布信息
        salesOffices.trigger('squareMeter88',2000000, 88);  // 发布一条
        salesOffices.trigger('squareMeter60',1500000, 60);  // 发布一条

    </script>

</body>

</html>